//
// Created by cy on 22-5-4.
//

#include "camera.hpp"
#include "armor.hpp"
#include <chrono>
#include <thread>
#include <csignal>

static volatile int SIGNAL_INT = 0;

void signal_handler(int sig) {
    if (sig == SIGINT) {
        SIGNAL_INT = 1;
    }
    if (sig == SIGTERM) {
        SIGNAL_INT = 1;
    }
}

int main() {
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    auto mainLogger = spdlog::stdout_color_st("MainOut");
    mainLogger->set_level(spdlog::level::info);
    mainLogger->flush_on(spdlog::level::info);

    auto armorFinder = ArmorFinder("../configs/armor.json", true);
    auto cam = Camera::getInstance("../configs/camera.Config");
    if (cam->open()) {
//            cam->setRoi(std::make_tuple(480, 384), std::make_tuple(320, 256));
        cam->setRoi(std::make_tuple(320, 256), std::make_tuple(640, 512));
//            cam->setExposureTime(3);
        cam->play();

        cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_ERROR);

        cv::Mat frame;
        bool ret = false;
        int times = 0;
        std::this_thread::sleep_for(std::chrono::seconds(1));
//            cam->softTrigger();
        std::tie(ret, frame, times) = cam->read(1000);
        auto lastTime = (float) times;
        int mode = 0;
        while (!SIGNAL_INT) {
//                cam->softTrigger();
            std::tie(ret, frame, times) = cam->read(0);
            if (ret) {
//                    mainLogger->info("已进入帧捕捉");
//                    auto timeState = ((float) times - lastTime) / 1000;
//                    mainLogger->info("每张图片时间间隔为 [{:.4f}] ms", timeState);
//                    lastTime = (float) times;
                // ---- test time ----
                auto lastTimeUp = std::chrono::steady_clock::now();
                armorFinder.update(times, frame);
                auto nowTimeUp = std::chrono::steady_clock::now();
                auto finalTime = double((nowTimeUp - lastTimeUp).count()) / 1000000;
                mainLogger->info("处理耗时：[{:.4f}] ms", finalTime);

                auto result = armorFinder.result();
                auto resultDebug = armorFinder.debugFramesInfo();
                if (!result.empty()) {
                    for (auto data: result) {
                        if (data.type == enuArmorType::TYPE_BIG) {
                            mainLogger->info(
                                    "检测到大装甲板：width->{}|height->{}|center->({}, {})",
                                    data.width, data.height, data.center.x, data.center.y
                            );
                        } else if (data.type == enuArmorType::TYPE_SMALL) {
                            mainLogger->info(
                                    "检测到小装甲板：width->{}|height->{}|center->({}, {})",
                                    data.width, data.height, data.center.x, data.center.y
                            );
                        }
                    }
                    mainLogger->info("----------");
                }
                if (mode == 0) {
                    cv::imshow("window", frame);
                } else {
                    cv::imshow("window", resultDebug[mode - 1]);
                }
                int key = cv::waitKey(1);
                mainLogger->info("mode->{}", mode);
                if (key == 100) {
                    if (mode < 4) {
                        mode += 1;
                    } else {
                        mode = 0;
                    }
                }
            } else {
//                    mainLogger->warn("超时等待1ms!!");
            }
        }
        cv::destroyAllWindows();
        cam->close();
    }
    return 0;
}